using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(CanvasGroup))]
public class AdvancedDialogueSystem : MonoBehaviour
{
    // ========== UI组件绑定 ==========
    [Header("UI Components")]
    [SerializeField] private RectTransform dialoguePanel;
    [SerializeField] private Text speakerText;
    [SerializeField] private Text contentText;
    [SerializeField] private ScrollRect textScroll;
    [SerializeField] private Image backgroundImage;
    [SerializeField] private GameObject choiceButtonPrefab;

    [Header("Configuration")]
    [Range(10, 60)] public float textSpeed = 30f;
    [SerializeField] private TextAsset storyFile;

    // ========== 运行时变量 ==========
    private List<string[]> scriptData = new List<string[]>();
    private int currentLine;
    private Coroutine typingCoroutine;
    private bool isTyping;
    private bool awaitingChoice;
    private CanvasGroup canvasGroup;

    [System.Serializable]
    public class CharacterConfig
    {
        public string characterName;
        public Transform leftSlot;
        public Transform rightSlot;
        public float fadeDuration = 0.5f;
    }

    [Header("Character Settings")]
    [SerializeField] private CharacterConfig characterConfig;
    [SerializeField] private Image characterPrefab;

    private Dictionary<string, Image> activeCharacters = new Dictionary<string, Image>();

    #region 初始化
    void Awake()
    {
        canvasGroup = GetComponent<CanvasGroup>();
        ValidateComponents();
    }

    void Start()
    {
        InitializeSystem();
        ExecuteNextCommand();
    }

    private void ValidateComponents()
    {
        Debug.Assert(dialoguePanel != null, "对话面板未绑定");
        Debug.Assert(speakerText != null, "说话人文本未绑定");
        Debug.Assert(contentText != null, "内容文本未绑定");
        Debug.Assert(textScroll != null, "滚动视图未绑定");
        Debug.Assert(backgroundImage != null, "背景图片未绑定");
        Debug.Assert(choiceButtonPrefab != null, "选项按钮预制体未绑定");
        Debug.Assert(storyFile != null, "剧本文件未绑定");
    }
    #endregion

    #region 系统初始化
    private void InitializeSystem()
    {
        ConfigureTextComponents();
        InitializeCharacterPool();
        ParseScript(storyFile.text);
        SetUIVisibility(true);
    }

    private void ConfigureTextComponents()
    {
        contentText.verticalOverflow = VerticalWrapMode.Overflow;
        contentText.horizontalOverflow = HorizontalWrapMode.Wrap;
        contentText.supportRichText = true;
    }

    private void SetUIVisibility(bool visible)
    {
        canvasGroup.alpha = visible ? 1 : 0;
        canvasGroup.blocksRaycasts = visible;
    }

    private void InitializeCharacterPool()
    {
        // 初始化左右位置容器
        if (characterConfig.leftSlot.childCount == 0)
        {
            var leftChar = Instantiate(characterPrefab, characterConfig.leftSlot);
            leftChar.gameObject.SetActive(false);
        }
        if (characterConfig.rightSlot.childCount == 0)
        {
            var rightChar = Instantiate(characterPrefab, characterConfig.rightSlot);
            rightChar.gameObject.SetActive(false);
        }
    }
    #endregion

    #region 输入处理
    void Update()
    {
        if (Input.GetMouseButtonDown(0) && !awaitingChoice)
        {
            HandlePlayerInput();
        }
    }

    private void HandlePlayerInput()
    {
        if (isTyping) CompleteTyping();
        else ProceedNext();
    }
    #endregion

    #region 剧本解析
    private void ParseScript(string script)
    {
        scriptData.Clear();
        foreach (var line in script.Split('\n'))
        {
            if (ShouldSkipLine(line)) continue;
            scriptData.Add(ProcessScriptLine(line));
        }
    }

    private bool ShouldSkipLine(string line)
    {
        return string.IsNullOrWhiteSpace(line) || line.StartsWith("//");
    }

    private string[] ProcessScriptLine(string line)
    {
        return line.Trim().Split('|');
    }
    #endregion

    #region 指令处理系统
    private void ExecuteNextCommand()
    {
        if (currentLine >= scriptData.Count)
        {
            EndStory();
            return;
        }

        ProcessCommand(scriptData[currentLine++]);
    }

    private void ProcessCommand(string[] cmd)
    {
        try
        {
            switch (cmd[0].ToUpper())
            {
                case "CHAR": HandleCharacterCommand(cmd); break;
                case "BG": HandleBackgroundCommand(cmd); break;
                case "DIALOGUE": HandleDialogueCommand(cmd); break;
                case "CHOICE": HandleChoiceCommand(cmd); break;
                default: HandleUnknownCommand(cmd); break;
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError($"指令执行错误: {e.Message}");
            ExecuteNextCommand();
        }
    }
    #endregion

    #region 背景系统
    private void HandleBackgroundCommand(string[] cmd)
    {
        if (cmd.Length < 2) throw new System.ArgumentException("BG指令参数不足");
        SetBackground(cmd[1]);
        ExecuteNextCommand();
    }

    private void SetBackground(string bgName)
    {
        var bg = Resources.Load<Sprite>($"Backgrounds/{bgName}");
        backgroundImage.sprite = bg ?? throw new System.ArgumentException($"找不到背景: {bgName}");
    }
    #endregion

    #region 对话系统
    private void HandleDialogueCommand(string[] cmd)
    {
        if (cmd.Length < 3) throw new System.ArgumentException("DIALOGUE指令参数不足");
        StartCoroutine(RunDialogueRoutine(cmd[1], cmd[2]));
    }

    private IEnumerator RunDialogueRoutine(string speaker, string content)
    {
        if (typingCoroutine != null)
        {
            StopCoroutine(typingCoroutine);
            typingCoroutine = null;
        }

        InitializeDialogueUI(speaker);
        yield return StartCoroutine(TypeText(content));
        FinalizeDialogue();
    }

    private void InitializeDialogueUI(string speaker)
    {
        speakerText.text = speaker;
        speakerText.gameObject.SetActive(!string.IsNullOrEmpty(speaker));
        contentText.text = "";
    }

    private IEnumerator TypeText(string text)
    {
        isTyping = true;
        typingCoroutine = StartCoroutine(InternalTypeText(text));
        yield return typingCoroutine;
        isTyping = false;
    }

    private IEnumerator InternalTypeText(string text)
    {
        foreach (char c in text)
        {
            contentText.text += c;
            UpdateScrollView();
            yield return new WaitForSeconds(1 / textSpeed);
        }
    }

    private void FinalizeDialogue()
    {
        UpdateScrollView();
        contentText.text = contentText.text.Trim();
    }
    #endregion

    #region 分支系统
    private void HandleChoiceCommand(string[] cmd)
    {
        if (cmd.Length < 3 || cmd.Length % 2 == 0)
            throw new System.ArgumentException("CHOICE指令参数错误");

        ShowChoiceButtons(cmd);
    }

    private void ShowChoiceButtons(string[] cmd)
    {
        awaitingChoice = true;
        ClearExistingChoices();
        CreateNewChoices(cmd);
    }

    private void ClearExistingChoices()
    {
        foreach (Transform child in textScroll.content)
        {
            if (child.CompareTag("ChoiceButton")) Destroy(child.gameObject);
        }
    }

    private void CreateNewChoices(string[] cmd)
    {
        for (int i = 1; i < cmd.Length; i += 2)
        {
            if (i + 1 >= cmd.Length) break;
            CreateChoiceButton(cmd[i], cmd[i + 1]);
        }
    }

    private void CreateChoiceButton(string text, string targetLine)
    {
        var button = Instantiate(choiceButtonPrefab, textScroll.content);
        button.GetComponentInChildren<Text>().text = text;
        button.GetComponent<Button>().onClick.AddListener(() => OnChoiceSelected(targetLine));
    }

    private void OnChoiceSelected(string targetLine)
    {
        if (!int.TryParse(targetLine, out int lineNumber))
            throw new System.ArgumentException("无效的行号格式");

        currentLine = lineNumber;
        awaitingChoice = false;
        ExecuteNextCommand();
    }
    #endregion

    #region 工具方法
    private void UpdateScrollView()
    {
        Canvas.ForceUpdateCanvases();
        textScroll.verticalNormalizedPosition = 0;
    }

    private void CompleteTyping()
    {
        if (typingCoroutine != null)
        {
            StopCoroutine(typingCoroutine);
            typingCoroutine = null;
        }

        if (currentLine > 0 && scriptData[currentLine - 1].Length > 2)
        {
            contentText.text = scriptData[currentLine - 1][2];
        }

        isTyping = false;
        UpdateScrollView();
    }

    private void ProceedNext() => ExecuteNextCommand();

    private void HandleUnknownCommand(string[] cmd)
    {
        Debug.LogWarning($"未知指令: {cmd[0]}");
        ExecuteNextCommand();
    }
    #endregion

    #region 立绘管理系统
    private void HandleCharacterCommand(string[] cmd)
    {
        if (cmd.Length < 4) throw new System.ArgumentException("CHAR指令参数不足");
        
        string position = cmd[1].ToLower();
        string charName = cmd[2];
        string emotion = cmd[3];

        switch (position)
        {
            case "left":
                UpdateCharacter(charName, emotion, characterConfig.leftSlot);
                break;
            case "right":
                UpdateCharacter(charName, emotion, characterConfig.rightSlot);
                break;
            case "hide":
                HideCharacter(cmd[2]);
                break;
            default:
                throw new System.ArgumentException($"未知位置参数: {position}");
        }
    }

    private void UpdateCharacter(string charName, string emotion, Transform slot)
    {
        // 获取或创建立绘实例
        if (!activeCharacters.TryGetValue(charName, out Image character))
        {
            character = Instantiate(characterPrefab, slot);
            activeCharacters.Add(charName, character);
        }

        // 加载表情资源
        Sprite emotionSprite = LoadEmotion(charName, emotion);
        StartCoroutine(FadeCharacter(character, emotionSprite));
    }

    private Sprite LoadEmotion(string charName, string emotion)
    {
        string path = $"Characters/{charName}/{emotion}";
        Sprite sprite = Resources.Load<Sprite>(path);
        
        if (sprite == null)
        {
            throw new System.ArgumentException($"找不到立绘资源: {path}");
        }
        return sprite;
    }

    private IEnumerator FadeCharacter(Image character, Sprite newSprite)
    {
        // 淡出旧立绘
        if (character.sprite != null)
        {
            float alpha = 1;
            while (alpha > 0)
            {
                alpha -= Time.deltaTime / characterConfig.fadeDuration;
                character.color = new Color(1, 1, 1, alpha);
                yield return null;
            }
        }

        // 更新立绘并淡入
        character.sprite = newSprite;
        character.gameObject.SetActive(true);
        
        float fadeIn = 0;
        while (fadeIn < 1)
        {
            fadeIn += Time.deltaTime / characterConfig.fadeDuration;
            character.color = new Color(1, 1, 1, fadeIn);
            yield return null;
        }
    }

    private void HideCharacter(string charName)
    {
        if (activeCharacters.TryGetValue(charName, out Image character))
        {
            StartCoroutine(FadeOutCharacter(character));
            activeCharacters.Remove(charName);
        }
    }

    private IEnumerator FadeOutCharacter(Image character)
    {
        float alpha = 1;
        while (alpha > 0)
        {
            alpha -= Time.deltaTime / characterConfig.fadeDuration;
            character.color = new Color(1, 1, 1, alpha);
            yield return null;
        }
        character.gameObject.SetActive(false);
    }
    #endregion

    private void EndStory()
    {
        SetUIVisibility(false);
        Debug.Log("剧本播放结束");
    }
}